package com.duniptech.soa.modeling;

import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.w3c.dom.Element;

import com.duniptech.soa.adapter.CoupledMicroSim;
import com.duniptech.soa.util.Util;

/**
 * @author  jlrisco
 */
public class AtomicMicroSim extends AtomicBase implements AtomicInterface {
	private com.duniptech.kernel.modeling.api.Atomic model;
	
	public AtomicMicroSim(Element xmlAtomic) throws Exception {
		super(xmlAtomic);
		if(Util.debug) System.out.println("AtomicMicroSim::AtomicMicroSim BEGIN");
		Object modelAux = null;
		String nodeName = xmlAtomic.getNodeName();
		if(nodeName.equals("coupled"))
			modelAux = new CoupledMicroSim((com.duniptech.kernel.modeling.api.Coupled)Class.forName(xmlAtomic.getAttribute("class")).newInstance());
		else if(nodeName.equals("atomic"))
			modelAux = Class.forName(xmlAtomic.getAttribute("class")).newInstance();
		this.model = (com.duniptech.kernel.modeling.api.Atomic)modelAux;
		if(Util.debug) System.out.println("AtomicMicroSim::AtomicMicroSim END: " + model);
	}
	
	public void initialize() {
	}
	
	public double ta() {
		double sigmaAux = model.ta();
		System.out.println(model.getName() + "(ta)=" + sigmaAux);
		if(sigmaAux>=com.duniptech.kernel.modeling.api.Devs.INFINITY)
			return Double.POSITIVE_INFINITY;
		return sigmaAux;
	}

	public void deltint() {
		model.deltint();
	}

	public void deltext(double e) {
		com.duniptech.kernel.modeling.api.Message message = buildMessage();
		model.deltext(e, message);
	}

	public void deltcon(double e) {
		com.duniptech.kernel.modeling.api.Message message = buildMessage();
		model.deltcon(e, message);
	}

	public void lambda() {
		com.duniptech.kernel.modeling.api.Message message = model.lambda();
		Iterator<String> itr = output.ports.keySet().iterator();
		while(itr.hasNext()) {
			String portName = itr.next();
			Collection<Object> values = message.getValuesOnPort(portName);
			for(Object value : values) {
				Port port = output.get(portName);
				if(port!=null)
					port.addValue(value);
			}
		}
	}
	
	public com.duniptech.kernel.modeling.api.Message buildMessage() {
		com.duniptech.kernel.modeling.api.Message message = new com.duniptech.kernel.modeling.MessageImpl();
		Map<String, Port> ports = input.ports;
		Iterator<String> itr = ports.keySet().iterator();
		while(itr.hasNext()) {
			String portName = itr.next();
			Set<Object> values = ports.get(portName).getValues();
			for(Object value : values) {
				message.add(portName, value);
			}
		}
		return message;
	}
}
